home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
math
/
newmat08
/
myexcept.h
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-17
|
10KB
|
328 lines
//$$ myexcept.h Exception handling classes
// A set of classes to simulate exceptions in C++
//
// Partially copied from Carlos Vidal's article in the C users' journal
// September 1992, pp 19-28
//
// Operations defined
// Try { }
// Throw ( exception object )
// Catch ( exception class ) { }
// CatchAll { }
// CatchAndThrow
//
// All catch lists must end with a CatchAll or CatchAndThrow statement
// but not both.
//
// When exceptions are finally implemented replace Try, Throw, Catch,
// CatchAll, CatchAndThrow by try, throw, catch, catch(...), and {}.
//
// All exception classes must be derived from Exception, have no non-static
// variables and must include functions
//
// static long st_type() { return 2; }
// long type() const { return 2; }
//
// where 2 is replaced by a prime number unique to the exception class.
// See notes for use with levels of exceptions.
//
#ifndef EXCEPTION_LIB
#define EXCEPTION_LIB
void Terminate();
/*********** classes for setting up exceptions and reporting ***************/
class Exception;
class Tracer // linked list showing how
{ // we got here
char* entry;
Tracer* previous;
public:
Tracer(char*);
~Tracer();
void ReName(char*);
friend class Exception;
};
class Exception // The base exception class
{
protected:
Exception() {}
public:
static Tracer* last; // points to Tracer list
static long st_type() { return 1; }
virtual long type() const { return 1; }
static void PrintTrace(Boolean=FALSE); // for printing trace
friend class Tracer;
Exception(int action);
Exception(const Exception&) {} // don't do anything
};
inline Tracer::Tracer(char* e)
: entry(e), previous(Exception::last) { Exception::last = this; }
inline Tracer::~Tracer() { Exception::last = previous; }
inline void Tracer::ReName(char* e) { entry=e; }
#ifdef SimulateExceptions // SimulateExceptions
#include <setjmp.h>
/************** the definitions of Try, Throw and Catch *******************/
class JumpItem;
class Janitor;
class JumpBase // pointer to a linked list of jmp_buf s
{
public:
static JumpItem *jl;
static long type; // type id. of last exception
static jmp_buf env;
};
class JumpItem // an item in a linked list of jmp_buf s
{
public:
JumpItem *ji;
jmp_buf env;
Tracer* trace; // to keep check on Tracer items
Janitor* janitor; // list of items for cleanup
JumpItem() : trace(0), janitor(0), ji(JumpBase::jl)
{ JumpBase::jl = this; }
~JumpItem() { JumpBase::jl = ji; }
};
void Throw(const Exception& exc);
void Throw();
#define Try \
if (!setjmp( JumpBase::jl->env )) { \
JumpBase::jl->trace = Exception::last; \
JumpItem JI387256156;
#define Bounce Throw()
#define Catch(EXCEPTION) \
} else if (JumpBase::type % EXCEPTION::st_type() == 0) {
#define CatchAll } else
#define CatchAndThrow } else Throw();
/******************* cleanup heap following Throw ************************/
class Janitor
{
protected:
static Boolean do_not_link; // set when new is called
Boolean OnStack; // false if created by new
public:
Janitor* NextJanitor;
virtual void CleanUp() {}
Janitor();
virtual ~Janitor();
};
// A tiresome old trick for initializing the Janitor class
// this is needed for classes derived from Janitor which have objects
// declared globally
class JanitorInitializer
{
public:
JanitorInitializer();
private:
static int ref_count;
};
static JanitorInitializer JanInit;
#endif // end of SimulateExceptions
#ifdef UseExceptions
#define Try try
#define Throw(E) throw E
#define Bounce throw
#define Catch catch
#define CatchAll catch(...)
#define CatchAndThrow {}
#endif // end of UseExceptions
#ifdef DisableExceptions // Disable exceptions
#define Try {
#define Bounce Throw()
#define Catch(EXCEPTION) } if (FALSE) {
#define CatchAll } if (FALSE)
#define CatchAndThrow }
inline void Throw() { Terminate(); }
inline void Throw(const Exception&) { Terminate(); }
#endif // end of DisableExceptions
#ifndef SimulateExceptions // ! SimulateExceptions
class Janitor // a dummy version
{
public:
virtual void CleanUp() {}
Janitor() {}
virtual ~Janitor() {}
};
#endif // end of ! SimulateExceptions
#ifdef DO_FREE_CHECK // DO_FREE_CHECK
// Routines for tracing whether new and delete calls are balanced
class FreeCheck;
class FreeCheckLink
{
protected:
FreeCheckLink* next;
void* ClassStore;
FreeCheckLink();
virtual void Report()=0; // print details of link
friend class FreeCheck;
};
class FCLClass : public FreeCheckLink // for registering objects
{
char* ClassName;
FCLClass(void* t, char* name);
void Report();
friend class FreeCheck;
};
class FCLRealArray : public FreeCheckLink // for registering real arrays
{
char* Operation;
int size;
FCLRealArray(void* t, char* o, int s);
void Report();
friend class FreeCheck;
};
class FCLIntArray : public FreeCheckLink // for registering int arrays
{
char* Operation;
int size;
FCLIntArray(void* t, char* o, int s);
void Report();
friend class FreeCheck;
};
class FreeCheck
{
static FreeCheckLink* next;
static int BadDelete;
public:
static void Register(void*, char*);
static void DeRegister(void*, char*);
static void RegisterR(void*, char*, int);
static void DeRegisterR(void*, char*, int);
static void RegisterI(void*, char*, int);
static void DeRegisterI(void*, char*, int);
static void Status();
friend class FreeCheckLink;
friend class FCLClass;
friend class FCLRealArray;
friend class FCLIntArray;
};
#define FREE_CHECK(Class) \
public: \
void* operator new(size_t size) \
{ \
void* t = ::operator new(size); FreeCheck::Register(t,#Class); \
return t; \
} \
void operator delete(void* t) \
{ FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
#ifdef SimulateExceptions // SimulateExceptions
#define NEW_DELETE(Class) \
public: \
void* operator new(size_t size) \
{ \
do_not_link=TRUE; \
void* t = ::operator new(size); FreeCheck::Register(t,#Class); \
return t; \
} \
void operator delete(void* t) \
{ FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
#endif // end of SimulateExceptions
#define MONITOR_REAL_NEW(Operation, Size, Pointer) \
FreeCheck::RegisterR(Pointer, Operation, Size);
#define MONITOR_INT_NEW(Operation, Size, Pointer) \
FreeCheck::RegisterI(Pointer, Operation, Size);
#define MONITOR_REAL_DELETE(Operation, Size, Pointer) \
FreeCheck::DeRegisterR(Pointer, Operation, Size);
#define MONITOR_INT_DELETE(Operation, Size, Pointer) \
FreeCheck::DeRegisterI(Pointer, Operation, Size);
#else // DO_FREE_CHECK not defined
#define FREE_CHECK(Class) public:
#define MONITOR_REAL_NEW(Operation, Size, Pointer) {}
#define MONITOR_INT_NEW(Operation, Size, Pointer) {}
#define MONITOR_REAL_DELETE(Operation, Size, Pointer) {}
#define MONITOR_INT_DELETE(Operation, Size, Pointer) {}
#ifdef SimulateExceptions // SimulateExceptions
#define NEW_DELETE(Class) \
public: \
void* operator new(size_t size) \
{ do_not_link=TRUE; void* t = ::operator new(size); return t; } \
void operator delete(void* t) { ::operator delete(t); }
#endif // end of SimulateExceptions
#endif // end of ! DO_FREE_CHECK
#ifndef SimulateExceptions // ! SimulateExceptions
#define NEW_DELETE(Class) FREE_CHECK(Class)
#endif // end of ! SimulateExceptions
#endif // end of ! EXCEPTION_LIB